﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using PoolGame2.Game;
using PoolGame2.Assets;

namespace PoolGame2.Menus
{
    public abstract class Menu : GameComponent
    {
        protected Texture2D backgroundTexture;
        protected float bgAlpha = 1.0f;
        protected List<MenuItem> menuItems = new List<MenuItem>();
        protected int iCurrentMenuSelection = 0;
        protected Vector2 position = GameConstants.MENU_POSITION;
        protected Vector2 size = new Vector2(640, 480);
        protected bool visible = true;

        public bool Visible
        {
            get { return visible; }
            set { visible = value; }
        }

        public float BGAlpha
        {
            get { return bgAlpha; }
            set { bgAlpha = value; }
        }

        public Menu(PoolGame game)
            : base(game)
        {
            backgroundTexture = game.textureDatabase.GetTexture("background");
            Viewport viewport = game.GraphicsDevice.Viewport;
            size = new Vector2(viewport.Width, viewport.Height);
        }

        public virtual bool IsModal() { return true; }
        public virtual void OnOpen()
        {
            if (IsModal())
            {
                PoolGame.gameControls.InMenu = true;
            }

            int item = GetFirstVisibleItem();
            if (iCurrentMenuSelection != item)
                menuItems[iCurrentMenuSelection].OnLeave();

            iCurrentMenuSelection = item;
            if (menuItems.Count > 0)
                menuItems[iCurrentMenuSelection].OnEntry();
        }

        public virtual void OnClose()
        {
            if (IsModal())
            {
                PoolGame.gameControls.InMenu = false;
            }
        }

        public void AddMenuItem(MenuItem item)
        {
            menuItems.Add(item);
        }

        public void RemoveMenuItem(MenuItem item)
        {
            menuItems.Remove(item);
        }

        public override void Update(GameTime gameTime)
        {
            if( menuItems.Count > 0 )
            {
                if (PoolGame.gameControls.MenuScrollDown())
                {
                    int newVal = 0;
                    if (GetVisibleItemCount() < 2)
                        newVal = GetFirstVisibleItem();
                    else
                    {
                        newVal = iCurrentMenuSelection;
                        do
                        {
                            newVal = (newVal + 1) % menuItems.Count;
                        } while (menuItems[newVal].Visible == false);
                    }
                    if (newVal != iCurrentMenuSelection)
                    {
                        menuItems[iCurrentMenuSelection].OnLeave();
                        iCurrentMenuSelection = newVal;
                        menuItems[iCurrentMenuSelection].OnEntry();
                    }
                }
                else if (PoolGame.gameControls.MenuScrollUp())
                {
                    int newVal = 0;
                    if (GetVisibleItemCount() < 2)
                        newVal = GetFirstVisibleItem();
                    else
                    {
                        newVal = iCurrentMenuSelection;
                        do
                        {

                            newVal = (newVal - 1) % menuItems.Count;
                            if (newVal < 0)
                                newVal = (menuItems.Count-1);
                        } while (menuItems[newVal].Visible == false);
                    }
                    if (newVal != iCurrentMenuSelection)
                    {
                        menuItems[iCurrentMenuSelection].OnLeave();

                        iCurrentMenuSelection = newVal;
                        menuItems[iCurrentMenuSelection].OnEntry();
                    }
                }
                else if (PoolGame.gameControls.MenuForwardAction())
                {
                    menuItems[iCurrentMenuSelection].OnSelect();
                }
            }

            foreach (MenuItem item in menuItems)
            {
                item.Update(gameTime);
            }

            base.Update(gameTime);
        }

        private int GetVisibleItemCount()
        {
            int vis = 0;
            for (int i = 0; i < menuItems.Count; i++)
            {
                if (menuItems[i].Visible)
                    vis++;
            }
            return vis;
        }

        private int GetFirstVisibleItem()
        {
            for (int i = 0; i < menuItems.Count; i++)
            {
                if (menuItems[i].Visible)
                    return i;
            }
            return 0;
        }

        public virtual void DrawBackground()
        {
            PoolGame poolGame = (PoolGame)Game;
            SpriteBatch spriteBatch = poolGame.spriteBatch;
            Rectangle fullscreen = new Rectangle(0, 0, (int)size.X, (int)size.Y);

            Color col = Color.White;
            col.A = (byte)(bgAlpha * 255);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
                spriteBatch.Draw(backgroundTexture, fullscreen, col);
            spriteBatch.End();
        }

        public virtual void Draw(GameTime gameTime)
        {
            DrawBackground();

            foreach (MenuItem item in menuItems)
            {
                item.Draw(gameTime, position);
            }
        }
    }
}
